<script lang="ts" setup>
import { reactive, ref, computed, nextTick } from "vue"
import { useRouter } from "vue-router"
import { useUserStore } from "@/store/modules/user"
import { type FormInstance, type FormRules } from "element-plus"
import { type RegisterRequestData, type UpdatePwdRequestData, type LoginRequestData } from "@/api/login/types/login"
import ThemeSwitch from "@/components/ThemeSwitch/index.vue"
import { useFocus } from "./hooks/useFocus"
import { ElMessage } from "element-plus"

const router = useRouter()
const { handleBlur, handleFocus } = useFocus()

/** 登录表单元素的引用 */
const loginFormRef = ref<FormInstance | null>(null)
const updatePwdFormRef = ref<FormInstance | null>(null)
const registerFormRef = ref<FormInstance | null>(null)

const type = ref("login")
const typeMap = ref<{ [propName: string]: string }>({
  login: "欢迎登录智能演进环境",
  updatePwd: "修改密码",
  register: "欢迎注册智能演进环境"
})
/** 登录按钮 Loading */
const loading = ref(false)

const validateIsAgree = (rule: any, value: any, callback: any) => {
  if (value === false) {
    callback(new Error("请阅读并同意服务协议与使用条款"))
  }
  callback()
}
const validateNewPass = (rule: any, value: any, callback: any) => {
  if (value === "") {
    callback(new Error("请输入新密码"))
  } else if (value.length < 5 || value.length > 20) {
    callback(new Error("长度在 5 到 20 个字符"))
  } else if (value === updatePwdFormData.password) {
    callback(new Error("新密码不能和旧密码相同"))
  }
  callback()
}
const rules = reactive<{
  login: FormRules
  updatePwd: FormRules
  register: FormRules
}>({
  /** 登录表单校验规则 */
  login: {
    user_name: [{ required: true, message: "请输入账号/手机号/邮箱", trigger: "blur" }],
    password: [
      { required: true, message: "请输入密码", trigger: "blur" },
      { min: 5, max: 20, message: "长度在 5 到 20 个字符", trigger: "blur" }
    ],
    isAgree: [{ required: true, trigger: "blur", validator: validateIsAgree }]
  },
  /** 更新密码 */
  updatePwd: {
    user_name: [{ required: true, message: "请输入账号/手机号/邮箱", trigger: "blur" }],
    password: [
      { required: true, message: "请输入旧密码", trigger: "blur" },
      { min: 5, max: 20, message: "长度在 5 到 20 个字符", trigger: "blur" }
    ],
    new_password: [{ required: true, trigger: "blur", validator: validateNewPass }],
    isAgree: [{ required: true, trigger: "blur", validator: validateIsAgree }]
  },
  /** 注册 */
  register: {
    user_name: [{ required: true, message: "请输入账号/手机号/邮箱", trigger: "blur" }],
    password: [
      { required: true, message: "请输入密码", trigger: "blur" },
      { min: 5, max: 20, message: "长度在 5 到 20 个字符", trigger: "blur" }
    ],
    user_position: [{ required: true, message: "职位不能为空", trigger: "blur" }],
    isAgree: [{ required: true, trigger: "blur", validator: validateIsAgree }]
  }
})
const HelloTitle = computed<string>(() => {
  return typeMap.value[type.value]
})
//#region 登录
/** 登录表单数据 */
const loginFormData: LoginRequestData = reactive({
  user_name: "",
  password: "",
  isAgree: false
})
/** 登录逻辑 */
const handleLogin = () => {
  loginFormRef.value?.validate((valid: boolean, fields) => {
    if (valid) {
      loading.value = true
      useUserStore()
        .login(loginFormData)
        .then(() => {
          router.push({ path: "/" })
        })
        .finally(() => {
          loading.value = false
        })
    } else {
      console.error("表单校验不通过", fields)
    }
  })
}
const handleToRegister = () => {
  resetLoginForm()
  type.value = "register"
}
/** 修改密码 */
const handleToUpdatePwd = () => {
  resetLoginForm()
  type.value = "updatePwd"
}
const resetLoginForm = () => {
  nextTick(() => {
    if (!loginFormRef.value) return
    loginFormRef.value.resetFields()
  })
}
//#endregion

//#region 注册
const registerFormData: RegisterRequestData = reactive({
  user_name: "",
  password: "",
  isAgree: false,
  user_position: ""
})
/** 注册 */
const handleRegister = () => {
  registerFormRef.value?.validate((valid: boolean, fields) => {
    if (valid) {
      loading.value = true
      useUserStore()
        .register(registerFormData)
        .then(() => {
          ElMessage.success("注册成功")
          type.value = "login"
          resetUpdatePwdForm()
        })
        .finally(() => {
          loading.value = false
        })
    } else {
      console.error("表单校验不通过", fields)
    }
  })
}
const resetRegisterForm = () => {
  nextTick(() => {
    if (!registerFormRef.value) return
    registerFormRef.value.resetFields()
  })
}
//#endregion

//#region 修改密码
const updatePwdFormData: UpdatePwdRequestData = reactive({
  user_name: "",
  password: "",
  isAgree: false,
  new_password: ""
})
/** 修改密码 */
const handleUpdatePwd = () => {
  updatePwdFormRef.value?.validate((valid: boolean, fields) => {
    if (valid) {
      loading.value = true
      useUserStore()
        .updatePwd(updatePwdFormData)
        .then(() => {
          ElMessage.success("密码修改成功")
          type.value = "login"
          resetUpdatePwdForm()
        })
        .finally(() => {
          loading.value = false
        })
    } else {
      console.error("表单校验不通过", fields)
    }
  })
}
const resetUpdatePwdForm = () => {
  nextTick(() => {
    if (!updatePwdFormRef.value) return
    updatePwdFormRef.value.resetFields()
  })
}
//#endregion
</script>

<template>
  <div class="login-container">
    <ThemeSwitch class="theme-switch" />
    <div class="login-card">
      <div class="title">
        <h1>{{ HelloTitle }}</h1>
      </div>
      <div class="content">
        <el-form
          v-if="type == 'login'"
          ref="loginFormRef"
          :model="loginFormData"
          :rules="rules['login']"
          @keyup.enter="handleLogin"
        >
          <el-form-item prop="user_name">
            <el-input
              v-model.trim="loginFormData.user_name"
              placeholder="请输入账号/手机号/邮箱"
              type="text"
              tabindex="1"
              size="large"
            />
          </el-form-item>
          <el-form-item prop="password">
            <el-input
              v-model.trim="loginFormData.password"
              placeholder="请输入密码"
              type="password"
              tabindex="2"
              size="large"
              show-password
              @blur="handleBlur"
              @focus="handleFocus"
            />
          </el-form-item>
          <div class="item item_update">
            <el-link :underline="false" type="info" @click.prevent="handleToUpdatePwd">修改密码</el-link>
          </div>
          <el-button :loading="loading" type="primary" size="large" @click.prevent="handleLogin">登 录</el-button>
          <el-button :underline="false" link type="info" size="large" @click.prevent="handleToRegister"
            >注册账号</el-button
          >
          <el-form-item prop="isAgree" class="form-item_error">
            <div class="item item_agree">
              <el-checkbox v-model="loginFormData.isAgree" size="large" label="我已经阅读并同意" />
              <el-link type="primary" :underline="false">服务协议与使用条款</el-link>
            </div>
          </el-form-item>
        </el-form>
        <el-form
          v-if="type == 'updatePwd'"
          ref="updatePwdFormRef"
          :model="updatePwdFormData"
          :rules="rules['updatePwd']"
          @keyup.enter="handleUpdatePwd"
        >
          <el-form-item prop="user_name">
            <el-input
              v-model.trim="updatePwdFormData.user_name"
              placeholder="请输入账号/手机号/邮箱"
              type="text"
              tabindex="1"
              size="large"
            />
          </el-form-item>
          <el-form-item prop="password">
            <el-input
              v-model.trim="updatePwdFormData.password"
              placeholder="请输入旧密码"
              type="password"
              tabindex="2"
              size="large"
              show-password
              @blur="handleBlur"
              @focus="handleFocus"
            />
          </el-form-item>
          <el-form-item v-if="type == 'updatePwd'" prop="new_password">
            <el-input
              v-model.trim="updatePwdFormData.new_password"
              placeholder="请输入新密码"
              type="password"
              tabindex="2"
              size="large"
              show-password
              @blur="handleBlur"
              @focus="handleFocus"
            />
          </el-form-item>
          <el-button :loading="loading" type="primary" size="large" @click.prevent="handleUpdatePwd"
            >确认修改</el-button
          >
          <el-button
            :underline="false"
            link
            type="info"
            size="large"
            @click.prevent="
              () => {
                resetUpdatePwdForm()
                type = 'login'
              }
            "
            >取消</el-button
          >
          <el-form-item prop="isAgree" class="form-item_error">
            <div class="item item_agree">
              <el-checkbox v-model="updatePwdFormData.isAgree" size="large" label="我已经阅读并同意" />
              <el-link type="primary" :underline="false">服务协议与使用条款</el-link>
            </div>
          </el-form-item>
        </el-form>
        <el-form
          v-if="type == 'register'"
          ref="registerFormRef"
          :model="registerFormData"
          :rules="rules['login']"
          @keyup.enter="handleRegister"
        >
          <el-form-item prop="user_name">
            <el-input
              v-model.trim="registerFormData.user_name"
              placeholder="请输入账号/手机号/邮箱"
              type="text"
              tabindex="1"
              size="large"
            />
          </el-form-item>
          <el-form-item prop="password">
            <el-input
              v-model.trim="registerFormData.password"
              placeholder="请输入密码"
              type="password"
              tabindex="2"
              size="large"
              show-password
              @blur="handleBlur"
              @focus="handleFocus"
            />
          </el-form-item>
          <el-form-item prop="user_position">
            <el-input
              v-model.trim="registerFormData.user_position"
              placeholder="请输入职位"
              type="text"
              tabindex="1"
              size="large"
            />
          </el-form-item>
          <el-button :loading="loading" type="primary" size="large" @click.prevent="handleRegister">注 册</el-button>
          <el-button
            :underline="false"
            link
            type="info"
            size="large"
            @click.prevent="
              () => {
                resetRegisterForm()
                type = 'login'
              }
            "
            >已有账号？返回登录</el-button
          >
          <el-form-item prop="isAgree" class="form-item_error">
            <div class="item item_agree">
              <el-checkbox v-model="registerFormData.isAgree" size="large" label="我已经阅读并同意" />
              <el-link type="primary" :underline="false">服务协议与使用条款</el-link>
            </div>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.login-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  min-height: 100%;
  .theme-switch {
    position: fixed;
    top: 5%;
    right: 5%;
    cursor: pointer;
  }
  .login-card {
    width: 480px;
    max-width: 90%;
    border-radius: 20px;
    box-shadow: 0 0 10px #dcdfe6;
    background-color: var(--el-bg-color);
    overflow: hidden;
    .title {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 150px;
      // img {
      //   height: 100%;
      // }
    }
    .content {
      padding: 0px 50px 50px 50px;
      :deep(.el-input-group__append) {
        padding: 0;
        overflow: hidden;
        .el-image {
          width: 100px;
          height: 40px;
          border-left: 0px;
          user-select: none;
          cursor: pointer;
          text-align: center;
        }
      }
      .el-button {
        width: 100%;
        margin-top: 10px;
      }
    }
  }
}
.form-item_flex-right {
  :deep(.el-form-item__content) {
    justify-content: right !important;
  }
}
.el-button + .el-button {
  margin-left: 0 !important;
}
.item {
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
}
.item_agree {
  justify-content: center;
  margin-top: 10px;
}
.item_update {
  justify-content: flex-end;
  margin-bottom: 10px;
}
:deep(.form-item_error .el-form-item__content) {
  .el-form-item__error {
    left: 60px !important;
  }
  .item_agree .el-checkbox__input.is-checked + .el-checkbox__label {
    color: #606266;
  }
  .el-checkbox:last-of-type {
    margin-right: 3px;
  }
}
</style>
